package com.ktgj.hotel.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ktgj.hotel.domain.HotelElongCity;
import com.ktgj.hotel.domain.base.HotelDetailInput;
import com.ktgj.hotel.domain.base.HotelDetailOutput;
import com.ktgj.hotel.domain.elong.*;
import com.ktgj.hotel.domain.rooms.*;
import com.ktgj.hotel.domain.vo.*;
import com.ktgj.hotel.mapper.HotelElongCityMapper;
import com.ktgj.hotel.utils.*;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.GZIPInputStream;

public class ElongUtils
{

    //泛型方法处理所有相同类型的接口
    public static <T> T getResult(T instance, T con,String methodInfo) {
        String url = "";
        String responseData = "";
        try {
            Long epoch = System.currentTimeMillis() / 1000;
            BaseRequest<T> req = new BaseRequest<>();
            req.Version = HotelUtils.version;
            req.Local = HotelUtils.locale;
            req.Request = con;
            String str = JSON.toJSONString(req);
            String sig = Encrypt.md5(epoch + Encrypt.md5(str + HotelUtils.ELONG_PREPAY_APPKEY) + HotelUtils.ELONG_PREPAY_SECRETKEY);
            url = "https" + "://" + HotelUtils.serverHost + "/rest?format=json&method=" + methodInfo;
            url += "&user=" + HotelUtils.ELONG_PREPAY_USER + "&timestamp=";
            url += epoch;
            url += "&signature=";
            url += sig;
            url += "&data=" + Encrypt.encodeUri(str);

//            NetUtils netUtils = new NetUtils();
//            Response response = null;
//            try {
//                response = netUtils.get(url);
//            } catch (Exception e){
//                e.printStackTrace();
//            }
//            Object json = JSONObject.toJSON(response);
//            System.out.println(json);
//            String respString = response.body().string();


//            BufferedReader br = null;
//            StringBuilder result = new StringBuilder();
//            InputStream in = new GZIPInputStream(response.body().byteStream());
//            br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
//            String line;
//            while ((line = br.readLine()) != null) {
//                result.append(line);
//                System.out.println(line);
//            }
//            JSONObject jsonObject = JSON.parseObject(result.toString());

//            instance = (T) JSON.parseObject(jsonObject.getString("Result"), instance.getClass());

            responseData = HttpsUtils.httpsGet(url);
            instance = (T) JSON.parseObject(responseData, instance.getClass());
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 查询酒店所有信息
     * @param input
     * @return
     */
    public static HotelDetailOutput queryByIdHotel(HotelDetailInput input) {
        HotelDetailOutput hotelDetailOutput = new HotelDetailOutput();
        input.Options = "1,2,3,4,12";
        hotelDetailOutput = (HotelDetailOutput) getResult(hotelDetailOutput, input, HotelUtils.HOTEL_DETAIL);
        return hotelDetailOutput;
    }

    /**
     * 修改酒店订单
     */
    public static HotelDetailOutput updateByIdHotel(HotelDetailInput input) {
        HotelDetailOutput hotelDetailOutput = new HotelDetailOutput();
        hotelDetailOutput = (HotelDetailOutput) getResult(hotelDetailOutput, input, HotelUtils.HOTEL_ORDER_UPDATE);
        return hotelDetailOutput;
    }

    /**
     * 目的地补全
     */
    public static HotelDetailOutput destination(HotelDetailInput input) {
        HotelDetailOutput hotelDetailOutput = new HotelDetailOutput();
        hotelDetailOutput = (HotelDetailOutput) getResult(hotelDetailOutput, input, HotelUtils.HOTEL_DESTINATION);
        return hotelDetailOutput;
    }

    /**
     * 酒店订单数据验证
     * */
    public HotelValidateOutPut validate(DataValidateVo dataValidateVo) throws Exception {
        HotelValidateOutPut hotelValidateOutPut = new HotelValidateOutPut();
        if (dataValidateVo.getArrivalDate() != null && !dataValidateVo.getArrivalDate().equals("") &&
                dataValidateVo.getDepartureDate() != null && !dataValidateVo.getDepartureDate().equals("") &&
                dataValidateVo.getEarliestArrivalTime() != null && !dataValidateVo.getEarliestArrivalTime().equals("") &&
                dataValidateVo.getLatestArrivalTime() != null && !dataValidateVo.getLatestArrivalTime().equals("") &&
                dataValidateVo.getHotelId() != null && !dataValidateVo.getHotelId().equals("") &&
                dataValidateVo.getRoomTypeID() != null && !dataValidateVo.getRoomTypeID().equals("") &&
                dataValidateVo.getRatePlanId() > 0 && dataValidateVo.getTotalPrice().compareTo(new BigDecimal(0)) == 1 &&
                dataValidateVo.getNumberOfRooms() > 0){
            hotelValidateOutPut = (HotelValidateOutPut) getResult(hotelValidateOutPut, dataValidateVo, HotelUtils.HOTEL_DATA_VALIDATE);
            if (hotelValidateOutPut.getCode().equals("0")){
                return hotelValidateOutPut;
            }
            else {
                throw new Exception("数据验证失败");
            }
        }
        else {
            throw new Exception("缺少必要参数");
        }
    }

    /**
     * 国内酒店-入住人姓名校验
     * */
    public static GuestName queryByIdGuestName(Name name) throws Exception {
        GuestName guestName = new GuestName();
        if (name != null && !name.equals("")){
            guestName = (GuestName) getResult(guestName, name, HotelUtils.HOTEL_ORDER_GUESTNAME_CHECK);
            if (guestName.getCode() == 0){
                return guestName;
            }
            else {
                throw new Exception("入住人姓名验证失败");
            }
        }
        else {
            throw new Exception("入住人姓名不能为空");
        }
    }

    /**
     * 国内酒店-汇率
     * @param condition
     * @return
     */
    public static ExchangeRateResult exchangeRate(ExchangeRateCondition condition) {
        ExchangeRateResult result = new ExchangeRateResult();
        try {
            result = (ExchangeRateResult) getResult(result, condition, HotelUtils.COMMON_EXCHANGERATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-信用卡验证
     * @param condition
     * @return
     */
    public static ValidateCreditCardResult validateCreditCard(ValidateCreditCardCondition condition) {
        ValidateCreditCardResult result = new ValidateCreditCardResult();
        try {
            Long epoch = System.currentTimeMillis() / 1000;
            if (condition.CreditCardNo != null) {
                condition.CreditCardNo = CipherUtil.desEncrypt(epoch.toString() + "#" + condition.CreditCardNo, HotelUtils.APPKEY.substring(HotelUtils.APPKEY.length() - 8));
            }
            result = (ValidateCreditCardResult) getResult(result, condition, HotelUtils.COMMON_CREDITCARD_VALIDATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-订单催确认
     * @param condition
     * @return
     */
    public static OrderPromoteResult orderPromote(OrderPromoteCondition condition) {
        OrderPromoteResult result = new OrderPromoteResult();
        try {
            result = (OrderPromoteResult) getResult(result, condition, HotelUtils.HOTEL_ORDER_PROMOTE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-下单前数据验证
     * @param condition
     * @return
     */
    public static ValidateResult hotelValidate(ValidateCondition condition) {
        ValidateResult result = new ValidateResult();
        try{
            result = (ValidateResult) getResult(result, condition, HotelUtils.HOTEL_DATA_VALIDATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-预定数据
     * @param condition
     * @return
     */
    public static BookingDataResult hotelBooking(BookingDataCondition condition) {
        BookingDataResult result = new BookingDataResult();
        try{
            result = (BookingDataResult) getResult(result, condition, HotelUtils.HOTEL_DATA_BOOKING);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 国内酒店-补开发票
     * @param condition
     * @return
     */
    public static AddInvoiceResult addInvoice(AddInvoiceCondition condition) {
        AddInvoiceResult result = new AddInvoiceResult();
        try {
            result = (AddInvoiceResult) getResult(result, condition, HotelUtils.HOTEL_ORDER_ADDINVOICE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-获取工单类别
     * @param condition
     * @return
     */
    public static SrFindDicResult srFindDic(SrFindDicCondition condition) {
        SrFindDicResult result = new SrFindDicResult();
        try {
            result = (SrFindDicResult) getResult(result, condition, HotelUtils.HOTEL_SR_FINDDIC);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-工单创建
     * @param condition
     * @return
     */
    public static SrCreateResult srCreate(SrCreateCondition condition) {
        SrCreateResult result = new SrCreateResult();
        try {
            result = (SrCreateResult) getResult(result, condition, HotelUtils.HOTEL_SR_CREATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-工单修改
     * @param condition
     * @return
     */
    public static SrModifyResult srModify(SrModifyCondition condition) {
        SrModifyResult result = new SrModifyResult();
        try {
            result = (SrModifyResult) getResult(result, condition, HotelUtils.HOTEL_SR_MODIFY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-工单催单
     * @param condition
     * @return
     */
    public static SrUrgeResult srUrge(SrUrgeCondition condition) {
        SrUrgeResult result = new SrUrgeResult();
        try {
            result = (SrUrgeResult) getResult(result, condition, HotelUtils.HOTEL_SR_URGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-获取工单可视化信息
     * @param condition
     * @return
     */
    public static SrVisualResult srVisual(SrVisualCondition condition) {
        SrVisualResult result = new SrVisualResult();
        try {
            result = (SrVisualResult) getResult(result, condition, HotelUtils.HOTEL_SR_VISUAL);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-修改订单
     * @param condition
     * @return
     */
    public static UpdateOrderR updateOrder(UpdateOrderCondition condition) {
        UpdateOrderR result = new UpdateOrderR();
        try {
            Long epoch = System.currentTimeMillis() / 1000;
            if (condition.getCreditCard() != null) {
                condition.getCreditCard().Number = CipherUtil.desEncrypt(epoch.toString() + "#" + condition.getCreditCard().Number, HotelUtils.APPKEY.substring(HotelUtils.APPKEY.length() - 8));
            }
            result = (UpdateOrderR) getResult(result, condition, HotelUtils.HOTEL_ORDER_UPDATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-订单支付确认
     * @param condition
     * @return
     */
    public static OrderPayConfirmResult orderPayConfirm(OrderPayConfirmCondition condition) {
        OrderPayConfirmResult result = new OrderPayConfirmResult();
        try{
            result = (OrderPayConfirmResult) getResult(result, condition, HotelUtils.HOTEL_ORDER_PAY_CONFIRM);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-订单支付
     * @param condition
     * @return
     */
    public static OrderPayResult orderPay(OrderPayCondition condition) {
        ValidateCreditCardCondition CVV = new ValidateCreditCardCondition();
        OrderPayResult result = new OrderPayResult();
        try {
            Long epoch = System.currentTimeMillis() / 1000;
            if (condition.CreditCard != null) {
                condition.CreditCard.Number = CipherUtil.desEncrypt(epoch.toString() + "#" + condition.CreditCard.Number, HotelUtils.APPKEY.substring(HotelUtils.APPKEY.length() - 8));
                condition.CreditCard.IdNo = CipherUtil.desEncrypt(epoch.toString() + "#" + condition.CreditCard.IdNo, HotelUtils.APPKEY.substring(HotelUtils.APPKEY.length() - 8));
                condition.CreditCard.CVV = CipherUtil.desEncrypt(epoch.toString() + "#" + condition.CreditCard.CVV, HotelUtils.APPKEY.substring(HotelUtils.APPKEY.length() - 8));
                CVV.CreditCardNo = condition.CreditCard.Number;
                ValidateCreditCardResult validateCreditCardResult = validateCreditCard(CVV);
                if (!validateCreditCardResult.Code.equals("0")) {
                    throw new Exception("此卡不可用,请重新输入");
                }
            }
            result = (OrderPayResult) getResult(result, condition, HotelUtils.HOTEL_ORDER_PAY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 国内酒店-订单详情
     * @param condition
     * @return
     */
    public static OrderDetailResult orderDetail(OrderIdCondition condition) {
        OrderDetailResult result = new OrderDetailResult();
        try {
            result = (OrderDetailResult) getResult(result, condition, HotelUtils.HOTEL_ORDER_DETAIL);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
